#ifndef __G_API_H__
#define __G_API_H__

#include "q_shared.h"

typedef struct
{
	void	(*Printf)( const char *fmt );
	void	(*Error)( const char *fmt );
	int		(*Milliseconds)( void );
	int		(*Argc)( void );
	void	(*Argv)( int n, char *buffer, int bufferLength );
	int		(*FS_FOpenFile)( const char *qpath, fileHandle_t *f, fsMode_t mode );
	int		(*FS_Read)( void *buffer, int len, int f );
	void	(*FS_Write)( const void *buffer, int len, int f );
	void	(*FS_FCloseFile)( int f );
	int		(*FS_GetFileList)( const char *path, const char *extension, char *listbuf, int bufsize );
	int		(*FS_Seek)( int f, long offset, int origin ); // fsOrigin_t
	void	(*SendConsoleCommand)( int exec_when, const char *text );
	void	(*Cvar_Register)( struct vmCvar_s *cvar, const char *var_name, const char *value, int flags );
	void	(*Cvar_Update)( struct vmCvar_s *cvar );
	void	(*Cvar_Set)( const char *var_name, const char *value );
	int		(*Cvar_VariableIntegerValue)( const char *var_name );
	float	(*Cvar_VariableValue)( const char *var_name );
	void	(*Cvar_VariableStringBuffer)( const char *var_name, char *buffer, int bufsize );
	void	(*LocateGameData)( struct gentity_s *gEnts, int numGEntities, int sizeofGEntity_t, int entityGDataCount, struct playerState_s *gameClients, int sizeofGameClient );
	void	(*DropClient)( int clientNum, const char *reason );
	void	(*SendServerCommand)( int clientNum, const char *text );
	void	(*SetConfigstring)( int num, const char *string );
	void	(*GetConfigstring)( int num, char *buffer, int bufferSize );
	void	(*GetUserinfo)( int num, char *buffer, int bufferSize );
	void	(*SetUserinfo)( int num, const char *buffer );
	void	(*GetServerinfo)( char *buffer, int bufferSize );
	void	(*SetBrushModel)( struct gentity_s *ent, const char *name );
	void	(*Trace)( struct trace_s *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask );
	int		(*PointContents)( const vec3_t point, int passEntityNum );
	qboolean (*InPVS)( const vec3_t p1, const vec3_t p2 );
	qboolean (*InPVSIgnorePortals)( const vec3_t p1, const vec3_t p2 );
	void	(*AdjustAreaPortalState)( struct gentity_s *ent, qboolean open );
	qboolean (*AreasConnected)( int area1, int area2 );
	void	(*LinkEntity)( struct gentity_s *ent );
	void	(*UnlinkEntity)( struct gentity_s *ent );
	int		(*EntitiesInBox)( const vec3_t mins, const vec3_t maxs, int *entityList, int maxcount );
	qboolean (*EntityContact)( const vec3_t mins, const vec3_t maxs, const struct gentity_s *ent );
	int		(*BotAllocateClient)( void );
	void	(*BotFreeClient)( int clientNum );
	void	(*GetUsercmd)( int clientNum, usercmd_t *cmd );
	qboolean	(*GetEntityToken)( char *buffer, int bufferSize );

	int		(*DebugPolygonCreate)(int color, int numPoints, vec3_t *points);
	void	(*DebugPolygonDelete)(int id);

	int		(*BotLibSetup)( void );
	int		(*BotLibShutdown)( void );
	int		(*BotLibVarSet)(char *var_name, char *value);
	int		(*BotLibVarGet)(char *var_name, char *value, int size);
	int		(*BotLibDefine)(char *string);
	int		(*BotLibStartFrame)(float time);
	int		(*BotLibLoadMap)(const char *mapname);
	int		(*BotLibUpdateEntity)(int ent, void /* struct bot_updateentity_s */ *bue);
	int		(*BotLibTest)(int parm0, char *parm1, vec3_t parm2, vec3_t parm3);

	int		(*BotGetSnapshotEntity)( int clientNum, int sequence );
	int		(*BotGetServerCommand)(int clientNum, char *message, int size);
	void	(*BotUserCommand)(int client, usercmd_t *ucmd);

	int		(*AAS_BBoxAreas)(vec3_t absmins, vec3_t absmaxs, int *areas, int maxareas);
	int		(*AAS_AreaInfo)( int areanum, void /* struct aas_areainfo_s */ *info );
	void	(*AAS_EntityInfo)(int entnum, void /* struct aas_entityinfo_s */ *info);

	int		(*AAS_Initialized)(void);
	void	(*AAS_PresenceTypeBoundingBox)(int presencetype, vec3_t mins, vec3_t maxs);
	float	(*AAS_Time)(void);

	int		(*AAS_PointAreaNum)(vec3_t point);
	int		(*AAS_PointReachabilityAreaIndex)(vec3_t point);
	int		(*AAS_TraceAreas)(vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas);

	int		(*AAS_PointContents)(vec3_t point);
	int		(*AAS_NextBSPEntity)(int ent);
	int		(*AAS_ValueForBSPEpairKey)(int ent, char *key, char *value, int size);
	int		(*AAS_VectorForBSPEpairKey)(int ent, char *key, vec3_t v);
	int		(*AAS_FloatForBSPEpairKey)(int ent, char *key, float *value);
	int		(*AAS_IntForBSPEpairKey)(int ent, char *key, int *value);

	int		(*AAS_AreaReachability)(int areanum);

	int		(*AAS_AreaTravelTimeToGoalArea)(int areanum, vec3_t origin, int goalareanum, int travelflags);
	int		(*AAS_EnableRoutingArea)( int areanum, int enable );
	int		(*AAS_PredictRoute)(void /*struct aas_predictroute_s*/ *route, int areanum, vec3_t origin,
								int goalareanum, int travelflags, int maxareas, int maxtime,
								int stopevent, int stopcontents, int stoptfl, int stopareanum);

	int		(*AAS_AlternativeRouteGoals)(vec3_t start, int startareanum, vec3_t goal, int goalareanum, int travelflags,
											void /*struct aas_altroutegoal_s*/ *altroutegoals, int maxaltroutegoals,
											int type);
	int		(*AAS_Swimming)(vec3_t origin);
	int		(*AAS_PredictClientMovement)(void /* aas_clientmove_s */ *move, int entnum, vec3_t origin, int presencetype, int onground, vec3_t velocity, vec3_t cmdmove, int cmdframes, int maxframes, float frametime, int stopevent, int stopareanum, int visualize);


	void	(*EA_Say)(int client, char *str);
	void	(*EA_SayTeam)(int client, char *str);
	void	(*EA_Command)(int client, char *command);

	void	(*EA_Action)(int client, int action);
	void	(*EA_Gesture)(int client);
	void	(*EA_Talk)(int client);
	void	(*EA_Attack)(int client);
	void	(*EA_Use)(int client);
	void	(*EA_Respawn)(int client);
	void	(*EA_Crouch)(int client);
	void	(*EA_MoveUp)(int client);
	void	(*EA_MoveDown)(int client);
	void	(*EA_MoveForward)(int client);
	void	(*EA_MoveBack)(int client);
	void	(*EA_MoveLeft)(int client);
	void	(*EA_MoveRight)(int client);
	void	(*EA_SelectWeapon)(int client, int weapon);
	void	(*EA_Jump)(int client);
	void	(*EA_DelayedJump)(int client);
	void	(*EA_Move)(int client, vec3_t dir, float speed);
	void	(*EA_View)(int client, vec3_t viewangles);

	void	(*EA_EndRegular)(int client, float thinktime);
	void	(*EA_GetInput)(int client, float thinktime, void /* struct bot_input_s */ *input);
	void	(*EA_ResetInput)(int client);


	int		(*BotLoadCharacter)(char *charfile, float skill);
	void	(*BotFreeCharacter)(int character);
	float	(*Characteristic_Float)(int character, int index);
	float	(*Characteristic_BFloat)(int character, int index, float min, float max);
	int		(*Characteristic_Integer)(int character, int index);
	int		(*Characteristic_BInteger)(int character, int index, int min, int max);
	void	(*Characteristic_String)(int character, int index, char *buf, int size);

	int		(*BotAllocChatState)(void);
	void	(*BotFreeChatState)(int handle);
	void	(*BotQueueConsoleMessage)(int chatstate, int type, char *message);
	void	(*BotRemoveConsoleMessage)(int chatstate, int handle);
	int		(*BotNextConsoleMessage)(int chatstate, void /* struct bot_consolemessage_s */ *cm);
	int		(*BotNumConsoleMessages)(int chatstate);
	void	(*BotInitialChat)(int chatstate, char *type, int mcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7 );
	int		(*BotNumInitialChats)(int chatstate, char *type);
	int		(*BotReplyChat)(int chatstate, char *message, int mcontext, int vcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7 );
	int		(*BotChatLength)(int chatstate);
	void	(*BotEnterChat)(int chatstate, int client, int sendto);
	void	(*BotGetChatMessage)(int chatstate, char *buf, int size);
	int		(*StringContains)(char *str1, char *str2, int casesensitive);
	int		(*BotFindMatch)(char *str, void /* struct bot_match_s */ *match, unsigned long int context);
	void	(*BotMatchVariable)(void /* struct bot_match_s */ *match, int variable, char *buf, int size);
	void	(*UnifyWhiteSpaces)(char *string);
	void	(*BotReplaceSynonyms)(char *string, unsigned long int context);
	int		(*BotLoadChatFile)(int chatstate, char *chatfile, char *chatname);
	void	(*BotSetChatGender)(int chatstate, int gender);
	void	(*BotSetChatName)(int chatstate, char *name, int client);
	void	(*BotResetGoalState)(int goalstate);
	void	(*BotRemoveFromAvoidGoals)(int goalstate, int number);
	void	(*BotResetAvoidGoals)(int goalstate);
	void	(*BotPushGoal)(int goalstate, void /* struct bot_goal_s */ *goal);
	void	(*BotPopGoal)(int goalstate);
	void	(*BotEmptyGoalStack)(int goalstate);
	void	(*BotDumpAvoidGoals)(int goalstate);
	void	(*BotDumpGoalStack)(int goalstate);
	void	(*BotGoalName)(int number, char *name, int size);
	int		(*BotGetTopGoal)(int goalstate, void /* struct bot_goal_s */ *goal);
	int		(*BotGetSecondGoal)(int goalstate, void /* struct bot_goal_s */ *goal);
	int		(*BotChooseLTGItem)(int goalstate, vec3_t origin, int *inventory, int travelflags);
	int		(*BotChooseNBGItem)(int goalstate, vec3_t origin, int *inventory, int travelflags, void /* struct bot_goal_s */ *ltg, float maxtime);
	int		(*BotTouchingGoal)(vec3_t origin, void /* struct bot_goal_s */ *goal);
	int		(*BotItemGoalInVisButNotVisible)(int viewer, vec3_t eye, vec3_t viewangles, void /* struct bot_goal_s */ *goal);
	int		(*BotGetNextCampSpotGoal)(int num, void /* struct bot_goal_s */ *goal);
	int		(*BotGetMapLocationGoal)(char *name, void /* struct bot_goal_s */ *goal);
	int		(*BotGetLevelItemGoal)(int index, char *classname, void /* struct bot_goal_s */ *goal);
	float	(*BotAvoidGoalTime)(int goalstate, int number);
	void	(*BotSetAvoidGoalTime)(int goalstate, int number, float avoidtime);
	void	(*BotInitLevelItems)(void);
	void	(*BotUpdateEntityItems)(void);
	int		(*BotLoadItemWeights)(int goalstate, char *filename);
	void	(*BotFreeItemWeights)(int goalstate);
	void	(*BotInterbreedGoalFuzzyLogic)(int parent1, int parent2, int child);
	void	(*BotSaveGoalFuzzyLogic)(int goalstate, char *filename);
	void	(*BotMutateGoalFuzzyLogic)(int goalstate, float range);
	int		(*BotAllocGoalState)(int state);
	void	(*BotFreeGoalState)(int handle);

	void	(*BotResetMoveState)(int movestate);
	void	(*BotMoveToGoal)(void /* struct bot_moveresult_s */ *result, int movestate, void /* struct bot_goal_s */ *goal, int travelflags);
	int		(*BotMoveInDirection)(int movestate, vec3_t dir, float speed, int type);
	void	(*BotResetAvoidReach)(int movestate);
	void	(*BotResetLastAvoidReach)(int movestate);
	int		(*BotReachabilityArea)(vec3_t origin, int testground);
	int		(*BotMovementViewTarget)(int movestate, void /* struct bot_goal_s */ *goal, int travelflags, float lookahead, vec3_t target);
	int		(*BotPredictVisiblePosition)(vec3_t origin, int areanum, void /* struct bot_goal_s */ *goal, int travelflags, vec3_t target);
	int		(*BotAllocMoveState)(void);
	void	(*BotFreeMoveState)(int handle);
	void	(*BotInitMoveState)(int handle, void /* struct bot_initmove_s */ *initmove);
	void	(*BotAddAvoidSpot)(int movestate, vec3_t origin, float radius, int type);

	int		(*BotChooseBestFightWeapon)(int weaponstate, int *inventory);
	void	(*BotGetWeaponInfo)(int weaponstate, int weapon, void /* struct weaponinfo_s */ *weaponinfo);
	int		(*BotLoadWeaponWeights)(int weaponstate, char *filename);
	int		(*BotAllocWeaponState)(void);
	void	(*BotFreeWeaponState)(int weaponstate);
	void	(*BotResetWeaponState)(int weaponstate);

	int		(*GeneticParentsAndChildSelection)(int numranks, float *ranks, int *parent1, int *parent2, int *child);

	void	(*Sys_SnapVector)( float *v );

	void	*(*Alloc)( int size, char *file, int line );
	void	(*Free)( void *v );
} gameImports_t;

typedef struct
{
	void (*InitGame)( int levelTime, int randomSeed, int restart );
	void (*ShutdownGame)( int restart );
	char *(*ClientConnect)( int clientNum, qboolean firstTime, qboolean isBot );
	void (*ClientThink)( int clientNum );
	void (*ClientUserinfoChanged)( int clientNum );
	void (*ClientDisconnect)( int clientNum );
	void (*ClientBegin)( int clientNum );
	void (*ClientCommand)( int clientNum );
	void (*RunFrame)( int levelTime );
	qboolean (*ConsoleCommand)();
	int (*BotAIStartFrame)( int time );
} gameExports_t;

#endif
